﻿define(function (require, exports, module) {
    var Config = require('config');
    var Canvas = require('canvas');
    var Area = require('area');
    var City = require('city');

    var m_mapLayer;
    //var m_
    var m_mapDatas;
    var m_x = m_y = 0;
    var m_dragable = false;
    var m_startX;
    var m_startY;

    function Map(data) {
        this.id = data.Id;
        this.x = data.X;
        this.y = data.Y;
        this.name = data.Name;
        this.areas = $.map(data.Areas, function (data) {
            return Area.createInstance(m_mapLayer, data);
        });
        this.cities = $.map(data.Cities, function (data) {
            return City.createInstance(m_mapLayer, data);
        });
    };

    Map.prototype.render = function (x, y) {
        $.each(this.areas, function () {
            this.renderOnMap(x, y);
        });
        $.each(this.cities, function () {
            this.renderOnMap(x, y);
        });
    };

    exports.init = function (data) {
        var halfWidth = (Config.getWidth() - data.MainCityWidth) / 2;
        if (data.MainCityX < halfWidth)
            m_x = 0
        else if (halfWidth < (Config.getMaxWidth() - data.MainCityX))
            m_x = Config.getMaxWidth() - halfWidth;
        else
            m_x = data.MainCityX + data.MainCityWidth / 2;

        var halfHeight = (Config.getHeight() - data.MainCityHeight) / 2;
        if (data.MainCityY < halfHeight)
            m_y = 0;
        else if (halfHeight < (Config.getMaxHeight() - data.MaxCityY))
            m_y = Config.getMaxHeight() - halfHeight;
        else
            m_y = data.MaxCityY + data.MainCityHeight / 2;

        m_mapDatas = data.Maps;
        this.render();
    };

    exports.render = function () {
        Canvas.clear();
        m_mapLayer = Canvas.createLayer();
        var maps = $.map(m_mapDatas, function (data) {
            var map = new Map(data);
            map.render(m_x, m_y);
            return map;
        });
        Canvas.add(m_mapLayer);

        m_mapLayer.on('mousedown', function (e) {
            m_dragable = true;
            m_startX = e.clientX;
            m_startY = e.clientY;
        });

        m_mapLayer.on('mouseup mouseleave', function (e) {
            if (!m_dragable) return;
            m_dragable = false;
            var p = calculateMapPosition(e);
            m_x = p.x;
            m_y = p.y;
        });

        m_mapLayer.on('mousemove', function (e) {
            if (!m_dragable) return;
            var p = calculateMapPosition(e);
            $.each(maps, function () {
                this.render(p.x, p.y);
            });
            m_mapLayer.draw();
        });
    };
    City.setRenderMap(exports.render);

    function calculateMapPosition(e) {
        var x = m_x - (e.clientX - m_startX);
        x = 0 < x ? (x <= Config.getMaxX() ? x : Config.getMaxX()) : 0;
        var y = m_y - (e.clientY - m_startY);
        y = 0 < y ? (y <= Config.getMaxY() ? y : Config.getMaxY()) : 0;
        return { x: x, y: y };
    };
});